#include <iostream>
#include <vector>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>

int main()
{
    // 注册SIGCHLD信号的处理方法为忽略子进程
    // 这样不会产生僵尸进程
    signal(SIGCHLD, SIG_IGN);   

    if(fork() == 0)
    {
        std::cout << "child process:" << getpid() << std::endl;
        exit(0);
    }

    while(true) {}

    return 0;
}

// 采用SIGCHLD信号等待子进程退出
// 采用waitpid， 设置-1非阻塞等待任意子进程退出
// std::vector<pid_t> childPid;

// void signal_handler(int sig)
// {
//     int status = 0;
//     pid_t n = 0;
//     size_t sz = childPid.size();

//     for(size_t i = 0; i < sz; ++i)
//     {
//         if((n = waitpid(childPid[i], &status, WNOHANG)) > 0)
//         {
//             std::cout << "child process exit, pid:" << n << \
//             ", exitcode:" << WEXITSTATUS(status) << std::endl; 
//         }
//     }
// }

// int main()
// {
//     signal(SIGCHLD, signal_handler);

//     std::cout << "father process, pid:" << getpid() << std::endl; 

//     pid_t id = 0;
//     for(int i = 0; i < 10; ++i)
//     {
//         id = fork();
//         if(id == 0)
//         {
//             std::cout << "child process:" << getpid() << std::endl;
//             exit(0);
//         }

//         childPid.push_back(id);
//     }

//     while(true) { }
//     return 0;
// }


// 采用SIGCHLD信号等待子进程退出
// 采用waitpid， 设置-1非阻塞等待任意子进程退出
// void signal_handler(int sig)
// {
//     int status = 0;
//     int count = 0;
//     while(waitpid(-1, &status, WNOHANG) > 0)
//     {
//         std::cout << "子进程退出成功" << WEXITSTATUS(status) << std::endl;
//         ++count;
//     }
//     if(count != 0) std::cout << "add count:" << count << std::endl;
// }

// int main()
// {
//     signal(SIGCHLD, signal_handler);

//     for(int i = 0; i < 10; ++i)
//     {
//         if(fork() == 0)
//         {
//             int count = 1;
//             while(count--)
//             { 
//                 sleep(1);
//             }
//             exit(0);
//         }
//     }

//     while(true) { }

//     return 0;
// }

// void signal_handler(int sig)
// {
//     std::cout << "recieve a signal, pid" << sig << std::endl;
// }

// int main()
// {
//     signal(SIGCHLD, signal_handler);

//     if(fork() == 0)
//     {
//         int count = 3;
//         while(count--)
//         {
//             std::cout << "child process, pid:" << getpid() << std::endl;
//             sleep(1);
//         }
//         exit(0);
//     }

//     while(true)
//     { }

//     return 0;
// }

// voliate关键字 -- 阻止编译器优化
// volatile int flag = 0;

// void signal_handler(int sig)
// {
//     std::cout << "flag change: " << flag;
//     flag = 1;
//     std::cout << "->" << flag << std::endl;
// }

// int main()
// {
//     signal(SIGINT, signal_handler);
//     std::cout << "pid:" << getpid() << std::endl;
//     while(!flag)
//     { }
//     std::cout << "process quit success" << std::endl;
//     return 0;
// }

// void showpending(const sigset_t& pending)
// {
//     for(int sig = 1; sig <= 31; ++sig)
//     {
//         if(sigismember(&pending, sig)) std::cout << 1;
//         else std::cout << 0;
//     }
//     std::cout << std::endl;
// }

// void signal_handler(int sig)
// {
//     std::cout << "Recieve a signal:" << sig << std::endl;

//     int count = 20;
//     sigset_t pending;

//     while(count--)
//     {
//         sigpending(&pending);
//         showpending(pending);
//         sleep(1);
//     }
// }

// int main()
// {
//     signal(SIGINT, SIG_IGN);
//     std::cout << "This is a process, pid:" << getpid() << std::endl;

//     struct sigaction act, oact;
    
//     act.sa_flags = 0;
//     act.sa_handler = signal_handler;

//     sigemptyset(&act.sa_mask);
//     sigaddset(&act.sa_mask, 2);   
//     sigaddset(&act.sa_mask, 3);   
//     sigaddset(&act.sa_mask, 4);   
//     sigaddset(&act.sa_mask, 5);   
//     sigaddset(&act.sa_mask, 6);   
//     sigaddset(&act.sa_mask, 7);   
//     sigaddset(&act.sa_mask, 8);   
//     sigaddset(&act.sa_mask, 9);   
//     sigaddset(&act.sa_mask, 10);   
//     sigaddset(&act.sa_mask, 11);   

//     sigaction(SIGINT, &act, &oact);  // 重新注册信号处理方法

//     std::cout << (int)(oact.sa_handler) << std::endl;
    
//     while(true) { }

//     return 0;
// }

// void signal_handler(int sig)
// {
//     int count = 5;
//     while(count--)
//     {
//         std::cout << "Recieve a signal:" << sig << std::endl;
//     }

//     sleep(10);
// }

// // 进程对每个信号，只能进行一层处理
// // 即：当进程处理一个信号的时候，必须设置对这个信号进行阻塞
// // 如果在处理特定信号的时候，进程又收到了这个信号，那么这个信号的pending设置为1
// // 等待本次处理完成之后，才可以再次处理这个信号
// // 如果进程在处理这个信号的时候，接收到了多次这个信号，那么它只能再次被处理一次
// // 因为，对于某个信号的未决状态，只有一个对应的二进制bit位，因此只能被保存一次
// int main()
// {
//     signal(SIGINT, signal_handler);
//     std::cout << "This is a father process, pid:" << getpid() << std::endl;
//     while(true) { }
//     return 0;
// }